
/* 
类泛型的3个操作:
    1. 定义泛型类型: 定义类的类名的右侧
    2. 使用泛型: 类内部
    3. 指定泛型对应的具体类型: 创建类的实例时, 在类名的右侧
*/
(() => {
  class GenericClass<T> {
    zeroValue: T
    add: (x: T, y: T) => T
  }

  const gc1 = new GenericClass<number>()
  gc1.zeroValue = 3
  gc1.add = function (x: number, y: number): number {
    return gc1.zeroValue + x + y
  }

  console.log(gc1.add(2, 3))

  const gc2 = new GenericClass<string>()
  gc2.zeroValue = 'abc'
  gc2.add = function (x: string, y: string): string {
    return gc1.zeroValue + x + y
  }

  console.log(gc2.add('ddd', 'eee'))
})()

;(() => {
  // 没有泛型约束
  function fn <T>(x: T): void {
    // console.log(x.length)  // error
  }

  interface Lengthwise {
    length: number;
  }

  /* 
  泛型约束: 对泛型确定的特性进行定义
  */
  function fn2 <T extends Lengthwise>(x: T): void {
    console.log(x.length)  // error
  }

  fn2('abc')
  // fn2(123) // error

})()